<script lang="ts" setup>
import { reactive, ref, watch } from "vue";
import iconfont from "@/assets/images/iconfont.json";
import type { VxeInputListeners, VxePulldownInstance } from "vxe-table";

const state = reactive<{ value: Nullable<string>; disabled: boolean; result: string[] }>({ value: null, disabled: false, result: [] });
const props = withDefaults(defineProps<{ modelValue?: Nullable<string>; disabled?: boolean }>(), { modelValue: null, disabled: false });
const emits = defineEmits<{ (event: "update:modelValue", value?: Nullable<string>): void }>();
const icons = iconfont.glyphs.map((g) => g.font_class).sort((a, b) => a.localeCompare(b, "en", { sensitivity: "base" }));

watch(
  () => props.modelValue,
  (newVal) => (state.value = newVal),
  { immediate: true },
);

watch(
  () => props.disabled,
  (newVal) => (state.disabled = newVal),
  { immediate: true },
);

const pulldownRef = ref<VxePulldownInstance>();
const inputEvents: VxeInputListeners = {
  focus() {
    const el = pulldownRef.value;
    if (el) el.showPanel();
    if (state.result.length === 0) handleSearch();
  },
  keyup() {
    handleSearch();
  },
};

function handleSearch() {
  state.result = icons.filter((i) => !state.value || i.indexOf(state.value) > -1).slice(0, 6);
}

function handleSelect(icon: string) {
  state.value = icon;
  emits("update:modelValue", icon);
  pulldownRef.value?.hidePanel();
}
</script>

<template>
  <vxe-pulldown ref="pulldownRef">
    <template #default>
      <vxe-input v-model="state.value" :disabled="state.disabled" @="inputEvents" placeholder="请输入图标关键字">
        <template #suffix><icon-symbol :name="state.value" /></template>
      </vxe-input>
    </template>
    <template #dropdown>
      <div class="vxe-select-option--wrapper">
        <div class="vxe-select-option" v-for="icon in state.result" :key="icon" @click="handleSelect(icon)">
          <icon-symbol class="drop-item" :name="icon" />
          <span v-text="icon"></span>
        </div>
      </div>
    </template>
  </vxe-pulldown>
</template>

<style lang="scss" scoped>
.drop-item {
  margin-right: 0.25rem;
}
.vxe-select-option {
  height: 2em;
  line-height: 2em;

  &:hover {
    background-color: #f5f7fa;
  }
}
</style>
